
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>

#include "list_view.h"
#include "event_listener.h"

namespace OHOS {
ListItem::~ListItem()
{
    if (itemText_ != nullptr) {
        delete itemText_;
        itemText_ = nullptr;
    }
    if (itemIcon_ != nullptr) {
        delete itemIcon_;
        itemIcon_ = nullptr;
    }
    if (background_ != nullptr) {
        delete background_;
        background_ = nullptr;
    }
    if (container_ != nullptr) {
        delete container_;
        container_ = nullptr;
    }
}

void ListItem::Create(UI_RECT rect)
{
    container_ = new UIViewGroup();
    container_->SetStyle(STYLE_BACKGROUND_COLOR, 0);
    container_->SetPosition(rect.x, rect.y, rect.w, rect.h);
    container_->SetTouchable(true);

    if (bkImage_.length() > 0) {
        background_ = new UIImageView();
        background_->SetPosition(0, 0, rect.w, rect.h);
        background_->SetSrc((char *)bkImage_.c_str());
        background_->SetStyle(STYLE_BACKGROUND_OPA, 0);
        background_->SetTouchable(true);

        container_->Add(background_);
    }
}

void ListItem::SetItem(const char *image, UI_RECT imageRect, const char *text, UI_RECT textRect, int fontSize)
{
    UITextLanguageAlignment alignment[STYLE_MAX] = {
        UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER,
        UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT,
        UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT
    };

    itemIcon_ = new UIImageView();
    itemIcon_->SetPosition(imageRect.x, imageRect.y, imageRect.w, imageRect.h);
    itemIcon_->SetSrc(image);
    itemIcon_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    itemIcon_->SetTouchable(true);
    container_->Add(itemIcon_);

    itemText_ = new UILabel();
    itemText_->SetPosition(textRect.x, textRect.y, textRect.w, textRect.h);
    itemText_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    itemText_->SetFont(FONT_NAME, fontSize);
    itemText_->SetText(text);
    itemText_->SetTouchable(true);
    if (style_ > STYLE_MAX) {
        style_ = 0;
    }
    itemText_->SetAlign(alignment[style_], UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
    container_->Add(itemText_);

    container_->Invalidate();
}

void ListItem::SetOnClick(UIView::OnClickListener *onClick)
{
    if (container_ == nullptr) {
        return;
    }
    container_->SetOnClickListener(onClick);

    if (itemIcon_ != nullptr) {
        itemIcon_->SetOnClickListener(onClick);
    }

    if (itemText_ != nullptr) {
        itemText_->SetOnClickListener(onClick);
    }
}

void ListItem::SetText(const char *text)
{
    if (itemText_ != nullptr) {
        itemText_->SetText(text);
    }
}

UIView* ListItem::GetView()
{
    return container_;
}

char* ListItem::GetText()
{
    if (itemText_ != nullptr) {
        return (char *)itemText_->GetText();
    }

    return nullptr;
}


class ListViewBackButtonClickListener : public UIView::OnClickListener {
public:
    ListViewBackButtonClickListener(UIView *view) : listView_(view) {}
    ~ListViewBackButtonClickListener(){}

    bool OnClick(UIView &view, const ClickEvent &event) override
    {
        listView_->SetVisible(true);
        listView_->Invalidate();

        return true;
    }

private:
    UIView *listView_;
};

static void ListViewClear(const UIView *view)
{
    if (view == nullptr || view->IsViewGroup == false) {
        return;
    }

    UIView *child = static_cast<const UIViewGroup*>(view)->GetChildrenHead();
    UIView *childNext = nullptr;

    while (child != nullptr) {
        childNext = child->GetNextSibling();
        if (child->IsViewGroup()) {
            ListViewClear(child);
        }
        delete child;
        child = childNext;
    }
}

ListView::~ListView()
{
    if (scroll_ != nullptr) {
        ListViewClear(scroll_);
        delete scroll_;
        scroll_ = nullptr;
    }

    if (title_ != nullptr) {
        delete title_;
        title_ = nullptr;
    }

    if (backButton_ != nullptr) {
        delete backButton_;
        backButton_ = nullptr;
    }

    if (background_ != nullptr) {
        delete background_;
        background_ = nullptr;
    }

    if (container_ != nullptr) {
        delete container_;
        container_ = nullptr;
    }

    list_.Clear();
}

static void SetUIRect(UI_RECT *rect, int x, int y, int w, int h)
{
    if (rect == nullptr) {
        return;
    }
    rect->x = x;
    rect->y = y;
    rect->w = w;
    rect->h = h;
}

void ListView::AddItem(const char *text, int idx)
{
    char fullPath[256] = {0};
    int x = LISTVIEW_START_X;
    int y = TITLE_HEIGHT + (LISTVIEW_START_Y + LINE_POS) * idx;
    int w = wodth_ - LISTVIEW_START_X * 2;                      // 2 cups of start x
    int h = LINE_HEIGHT;

    char *sliceName = nullptr;
    char iconPath[256] = {0};
    char *iconHead = GetSrcPath();
    if (fileType_ > FILE_TYPE_UNKNOW) {
        fileType_ = FILE_TYPE_UNKNOW;
    }

    if (fileType_ == FILE_TYPE_VIDEO) {
        (void)sprintf_s(fullPath, sizeof(fullPath), MENU_FILE_PATH"%s", text);
        (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, ICON_VIDEO_PATH_S);
        sliceName = "PlayerAbilitySlice";
    } else if (fileType_ == FILE_TYPE_IMAGE) {
        (void)sprintf_s(fullPath, sizeof(fullPath), MENU_FILE_PATH"%s", text);
        (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, iconimage_PATH_S);
        sliceName = "PictureAbilitySlice";
    } else {
        (void)sprintf_s(fullPath, sizeof(fullPath), MENU_FILE_PATH"%s", text);
        (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, ICON_UNKNOW_PATH);
        sliceName = "UnknowAbilitySlice";
    }

    ListItem *item = new ListItem("", ListItem::STYLE_LEFT_RIGHT);
    UI_RECT mainRect, imageRect, textRect;
    SetUIRect(&mainRect, x, y, w, h);
    SetUIRect(&imageRect, ICON_START_X, ICON_START_Y + y, ICON_WIDTH, ICON_HEIGHT);
    SetUIRect(&textRect, TEXT_START_X, ICON_START_Y + y, w - ICON_START_X - ICON_WIDTH, ICON_HEIGHT);

    item->Create(mainRect);
    item->SetItem((char *)iconPath, imageRect, text, textRect, FONT_SIZE_20);

    UIView *view = item->GetView();
    scroll_->Add(view);

    HoodsButtonClickListener *itemClick = new HoodsButtonClickListener(slice_);
    itemClick->SetSliceInfo((const char *)sliceName, (const char *)fullPath);
    item->SetOnClick(itemClick);
}

void ListView::Create(UI_RECT rect, const char *backImage)
{
    container_ = newUIViewGroup();
    container_->SetPosition(rect.x, rect.y, rect.w, rect.h);
    container_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    width_ = rect.w;
    height_ = rect.h;

    if (backImage != nullptr) {
        background_ = new UIImageView();
        background_->SetPosition(0, 0, rect.w, rect.h);
        background_->SetSrc(backImage);
        background_->SetStyle(STYLE_BACKGROUND_OPA, 0);

        container_->Add(background_);
    }

    char iconPath[256] = {0};
    const char *iconHead = GetSrcPath();
    (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, ICON_BACK0_PATH);
    backButton_ = new UIImageView();
    backButton_->SetPosition(BACK_ICON_XPOS, BACK_ICON_YPOS, BACK_ICON_WIDTH, BACK_ICON_HEIGHT);
    backButton_->SetSrc((char *)iconPath);
    backButton_->SetTouchable(true);
    backButton_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    container_->Add(background_);

    ListViewBackButtonClickListener *clicker = new ListViewBackButtonClickListener(container_);
    backButton_->SetOnClickListener(clicker);

    if (titleName_.length() > 0) {
        title_ = new UILabel();
        title_->SetPosition(BACK_ICON_XPOS + BACK_ICON_WIDTH + LISTVIEW_START_X, BACK_ICON_YPOS,
                            rect.w - BACK_ICON_WIDTH, BACK_ICON_HEIGHT);
        title_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
        title_->SetStyle(STYLE_BACKGROUND_OPA, 0);
        title_->SetFont(FONT_NAME, FONT_SIZE_32);
        title_->SetText((char *)titleName_.c_str());
        title_->SetTouchable(true);
        title_->SetOnClickListener(clicker);
        container_->Add(title_);
    }

    scroll_ = new UIScrollView();
    scroll_->SetPosition(0, TITLE_HEIGHT + 1, rect.w, rect.h - TITLE_HEIGHT);
    scroll_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    container_->Add(scroll_);
}

void ListView::SetList(List<string> list)
{
    if (list.size() == 0) {
        return;
    }

    if (!list_.IsEmpty()) {
        list_.Clear();
    }

    ListNode<string> *pNode = list.Begin();
    for (int i = 0; i < list.size() && pNode != nullptr; i++) {
        string data = pNode->data_;
        list_.PushBack(data);
        pNode = pNode->next_;
        AddItem((const char *)data.c_str(), i);
    }

    scroll_->Invalidate();
}

void ListView::Update(List<string> list)
{
    list_.Clear();
    ListViewClear(scroll_);
    SetList(list);
}

void ListView::Display()
{
    if (container_ == nullptr) {
        return;
    }

    container_->SetVisible(true);
    container_->Invalidate();
}

void ListView::Dismiss()
{
    if (container_ == nullptr) {
        return;
    }

    container_->SetVisible(false);
    container_->Invalidate();
}

UIVIew* ListView::GetView()
{
    return container_;
}
}
